home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / disk / misc / memdev37_3.lha / memory-device / source / device.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-29  |  6.5 KB  |  278 lines

  1. /*
  2. ** $VER: device.c 1.2 (29 Mar 1996)(10 Mar 1996)
  3. **
  4. ** memory.device - direct memory access
  5. **
  6. ** (C) Copyright 1996 Marius Gröger
  7. **     All Rights Reserved
  8. **
  9. ** Inspired by z2ram device in Linux/68k/Amiga
  10. **
  11. ** $HISTORY:
  12. **
  13. ** 29 Mar 1996 : 001.002 :  minor changes
  14. ** 10 Mar 1996 : 001.001 :  + CMD_UPDATE does CacheClearU()
  15. **                          + using CopyMemWarp()
  16. ** 20 Dec 1995 : 001.000 :  created
  17. */
  18.  
  19. #define DEBUG 0
  20.  
  21. /*F*/ /* includes */
  22. #ifndef CLIB_ALIB_PROTOS_H
  23. #include <clib/alib_protos.h>
  24. #endif
  25. #ifndef CLIB_EXEC_PROTOS_H
  26. #include <clib/exec_protos.h>
  27. #include <pragmas/exec_sysbase_pragmas.h>
  28. #endif
  29.  
  30. #ifndef EXEC_MEMORY_H
  31. #include <exec/memory.h>
  32. #endif
  33. #ifndef EXEC_IO_H
  34. #include <exec/io.h>
  35. #endif
  36. #ifndef EXEC_ERRORS_H
  37. #include <exec/errors.h>
  38. #endif
  39. #ifndef DEVICES_TRACKDISK_H
  40. #include <devices/trackdisk.h>
  41. #endif
  42.  
  43. #ifndef _STRING_H
  44. #include <string.h>
  45. #endif
  46.  
  47. #ifndef __MEMORY_H
  48. #include "memory.h"
  49. #endif
  50. #ifndef __DEBUG_H
  51. #include "debug.h"
  52. #endif
  53. #ifndef __COMPILER_H
  54. #include "compiler.h"
  55. #endif
  56. /*E*/
  57.  
  58. /*F*/ /* imports */
  59. PUBLIC ASM VOID CopyMemWarp(REG(a0) VOID *src, REG(a1) VOID *dst, REG(d0) ULONG len);
  60. /*E*/
  61. /*F*/ /* exports */
  62. PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) ULONG seglist, REG(a6) struct Library *_SysBase);
  63. PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOExtTD *iotd, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR);
  64. PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR);
  65. PUBLIC ASM SAVEDS BPTR DevClose( REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR);
  66. PUBLIC VOID DevTermIO(BASEPTR, struct IOExtTD *iotd);
  67. PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOExtTD *iotd, REG(a6) BASEPTR);
  68. PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR);
  69. /*E*/
  70. /*F*/ /* private */
  71. /*E*/
  72.  
  73.  
  74.    /*
  75.    ** initialise device
  76.    */
  77. /*F*/ PUBLIC ASM SAVEDS struct Device *DevInit(REG(d0) BASEPTR, REG(a0) ULONG seglist, REG(a6) struct Library *_SysBase)
  78. {
  79.    BOOL ok;
  80.    UBYTE *p;
  81.    UWORD i;
  82.  
  83.    d(("entered device, initialising device base...\n"));
  84.  
  85.       /* clear data base */
  86.    for(p = ((UBYTE*)mb) + sizeof(struct Library), i = sizeof(struct MemoryBase)-sizeof(struct Library); i; i--)
  87.       *p++ = 0;
  88.  
  89.    SysBase = _SysBase;
  90.  
  91.    mb->mb_SegList = seglist;           /* store DOS segment list */
  92.  
  93.    InitSemaphore(&mb->mb_Lock);
  94.  
  95.    ok = TRUE;
  96.  
  97.    d(("left %ld\n",ok));
  98.  
  99.    return (struct Device *)(ok ? mb : NULL);
  100. }
  101. /*E*/
  102.  
  103.    /*
  104.    ** open device
  105.    */
  106. /*F*/ PUBLIC ASM SAVEDS LONG DevOpen(REG(a1) struct IOExtTD *iotd, REG(d0) ULONG unit, REG(d1) ULONG flags, REG(a6) BASEPTR)
  107. {
  108.    LONG rv = 0;
  109.  
  110.    d(("entered\n"));
  111.  
  112.    /* Make sure our open remains single-threaded. */
  113.    ObtainSemaphore(&mb->mb_Lock);
  114.    mb->mb_DevNode.lib_OpenCnt++;
  115.    mb->mb_DevNode.lib_Flags &= ~LIBF_DELEXP;
  116.    ReleaseSemaphore(&mb->mb_Lock);
  117.  
  118.    iotd->iotd_Req.io_Error = 0;
  119.    iotd->iotd_Req.io_Unit = NULL;
  120.    iotd->iotd_Req.io_Device = (struct Device *)mb;
  121.    iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
  122.  
  123.    return rv;
  124. }
  125. /*E*/
  126.  
  127.    /*
  128.    ** close device
  129.    */
  130. /*F*/ PUBLIC ASM SAVEDS BPTR DevClose(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR)
  131. {
  132.    BPTR seglist;
  133.  
  134.    d2(("entered\n"));
  135.  
  136.       /* invalidate IO request block */
  137.    ior->iotd_Req.io_Device = (struct Device *)-1;
  138.    ior->iotd_Req.io_Unit = (struct Unit *)-1;
  139.  
  140.    ObtainSemaphore(&mb->mb_Lock);
  141.  
  142.    mb->mb_DevNode.lib_OpenCnt--;
  143.  
  144.    ReleaseSemaphore(&mb->mb_Lock);
  145.  
  146.    if (mb->mb_DevNode.lib_Flags & LIBF_DELEXP)
  147.       seglist = DevExpunge(mb);
  148.    else
  149.       seglist = 0;
  150.  
  151.    return seglist;
  152. }
  153. /*E*/
  154. /*F*/ PUBLIC ASM SAVEDS BPTR DevExpunge(REG(a6) BASEPTR)
  155. {
  156.    BPTR seglist;
  157.  
  158.    d2(("entered\n"));
  159.  
  160.    if (mb->mb_DevNode.lib_OpenCnt)
  161.    {
  162.       mb->mb_DevNode.lib_Flags |= LIBF_DELEXP;
  163.       seglist = 0;
  164.    }
  165.    else
  166.    {
  167.          /* detach device from system list */
  168.       Remove((struct Node*)mb);
  169.  
  170.          /* save seglist for return value */
  171.       seglist = (long)mb->mb_SegList;
  172.  
  173.          /* return memory
  174.          **
  175.          ** NO FURTHER ACCESS TO DEVICE BASE ALLOWED!
  176.          */
  177.       FreeMem(((char *)mb) - mb->mb_DevNode.lib_NegSize,
  178.          (ULONG)(mb->mb_DevNode.lib_PosSize + mb->mb_DevNode.lib_NegSize));
  179.    }
  180.  
  181.    return seglist;
  182. }
  183. /*E*/
  184.  
  185.    /*
  186.    ** initiate io command (1st level dispatcher)
  187.    */
  188. #if 0
  189. /*F*/ static INLINE VOID DevForwardIO(BASEPTR, struct IOExtTD *iotd)
  190. {
  191.    d(("forwarding request %ld\n", iotd->iotd_Req.io_Command));
  192.  
  193.    /* request is no longer of type "quick i/o" */
  194.    iotd->iotd_Req.io_Flags &= ~IOF_QUICK;
  195.    PutMsg(mb->mb_ServerPort, (struct Message*)iotd);
  196. }
  197. /*E*/
  198. #endif
  199. /*F*/ PUBLIC INLINE VOID DevTermIO(BASEPTR, struct IOExtTD *iotd)
  200. {
  201.    d(("cmd = %ld, error = %ld, wireerror = %ld\n", iotd->iotd_Req.io_Command, iotd->iotd_Req.io_Error,iotd->iotd_WireError));
  202.  
  203.                   /* if this command was done asynchonously, we must
  204.                   ** reply the request
  205.                   */
  206.    if(!(iotd->iotd_Req.io_Flags & IOF_QUICK))
  207.       ReplyMsg((struct Message *)iotd);
  208.    else           /* otherwise just mark it as done */
  209.       iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
  210. }
  211. /*E*/
  212. /*F*/ PUBLIC ASM SAVEDS VOID DevBeginIO(REG(a1) struct IOExtTD *iotd, REG(a6) BASEPTR)
  213. {
  214.       /* mark request as active */
  215.    iotd->iotd_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  216.    iotd->iotd_Req.io_Error = 0;
  217.  
  218.    d(("cmd = %ld\n",iotd->iotd_Req.io_Command));
  219.  
  220.    switch(iotd->iotd_Req.io_Command)
  221.    {
  222.       case CMD_READ:
  223.          CopyMemWarp((UBYTE*)iotd->iotd_Req.io_Offset, (UBYTE*)iotd->iotd_Req.io_Data,
  224.                   (ULONG)iotd->iotd_Req.io_Length);
  225.          iotd->iotd_Req.io_Actual = iotd->iotd_Req.io_Length;
  226.       break;
  227.  
  228.       case CMD_WRITE:
  229.          CopyMemWarp((UBYTE*)iotd->iotd_Req.io_Data, (UBYTE*)iotd->iotd_Req.io_Offset,
  230.                   (ULONG)iotd->iotd_Req.io_Length);
  231.          iotd->iotd_Req.io_Actual = iotd->iotd_Req.io_Length;
  232.       break;
  233.  
  234.       case CMD_UPDATE:
  235.          CacheClearU();
  236.       break;
  237.  
  238.       case CMD_RESET:
  239.       case CMD_CLEAR:
  240.       case CMD_STOP:
  241.       case CMD_START:
  242.       break;
  243.  
  244.       case TD_PROTSTATUS:
  245.          iotd->iotd_Req.io_Actual = 0; /* not protected */
  246.       break;
  247.  
  248.       case TD_MOTOR:
  249.          iotd->iotd_Req.io_Actual = 0;
  250.       break;
  251.  
  252.       case TD_FORMAT:
  253.          iotd->iotd_Req.io_Actual = iotd->iotd_Req.io_Length;
  254.       break;
  255.  
  256.       default:
  257.          iotd->iotd_Req.io_Error = IOERR_NOCMD;
  258.       break;
  259.    }
  260.  
  261.    if (iotd) DevTermIO(mb, iotd);
  262.  
  263.    return;
  264. }
  265. /*E*/
  266.  
  267.    /*
  268.    ** stop io-command
  269.    */
  270. /*F*/ PUBLIC ASM SAVEDS LONG DevAbortIO(REG(a1) struct IOExtTD *ior, REG(a6) BASEPTR)
  271. {
  272.    d(("cmd = %ld\n",ior->iotd_Req.io_Command));
  273.  
  274.    return 0;
  275. }
  276. /*E*/
  277.  
  278.